!pip install pandas matplotlib numpy statsmodels seaborn scipy -q
[notice] A new release of pip is available: 24.3.1 -> 25.1.1 [notice] To update, run: pip install --upgrade pip
# Import all datasets for sit to stand
import pandas as pd
from data_collector import get_sit_to_stand_paths, get_sit_to_stand_challenge_paths, get_water_task_paths, get_water_task_challenge_paths, get_step_count_paths, get_step_count_challenge_paths
import numpy as np
task = 'step_count'
if task == 'sit2stand':
paths_standard = get_sit_to_stand_paths()
paths_challenge = get_sit_to_stand_challenge_paths()
elif task == 'water':
paths_standard = get_water_task_paths()
paths_challenge = get_water_task_challenge_paths()
elif task == 'step_count':
paths_standard = get_step_count_paths()
paths_challenge = get_step_count_challenge_paths()
dfs_stand = [pd.read_csv(path) for path in paths_standard]
dfs_stand_challenge = [pd.read_csv(path) for path in paths_challenge]
# For each dataframe, add a new column 'time_s' which is the time in seconds from the first timestamp
for df in dfs_stand:
df['time_s'] = (df['timestamp_ms'] - df['timestamp_ms'].min()) / 1000
for df in dfs_stand_challenge:
df['time_s'] = (df['timestamp_ms'] - df['timestamp_ms'].min()) / 1000
if task=='step_count':
# rename column from acceleration_m/s²_x to 'freeAcceleration_m/s²_x' for x y and z
dfs_stand = [df.rename(columns={'acceleration_m/s²_x': 'freeAcceleration_m/s²_x', 'acceleration_m/s²_y': 'freeAcceleration_m/s²_y', 'acceleration_m/s²_z': 'freeAcceleration_m/s²_z'}) for df in dfs_stand]
dfs_stand_challenge = [df.rename(columns={'acceleration_m/s²_x': 'freeAcceleration_m/s²_x', 'acceleration_m/s²_y': 'freeAcceleration_m/s²_y', 'acceleration_m/s²_z': 'freeAcceleration_m/s²_z'}) for df in dfs_stand_challenge]
# Calculate magnitude of acceleration
for df in dfs_stand:
df['acceleration_magnitude'] = np.sqrt(
df['freeAcceleration_m/s²_x']**2 +
df['freeAcceleration_m/s²_y']**2 +
df['freeAcceleration_m/s²_z']**2
)
for df in dfs_stand_challenge:
df['acceleration_magnitude'] = np.sqrt(
df['freeAcceleration_m/s²_x']**2 +
df['freeAcceleration_m/s²_y']**2 +
df['freeAcceleration_m/s²_z']**2
)
df_standard = dfs_stand[0]
df_challenge = dfs_stand_challenge[0]
print(f"Using data from {paths_standard[0]} and {paths_challenge[0]}")
Data directory to look in: /Users/ashish/Desktop/DS4W/sensorhub-analysis/data Sub directories for each Device ID found: ['f3eba7e5-dbda-4f4c-9fa8-8e8308b334f6', '5f680dfb-2510-4790-8f10-cb8724e7004c', '3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8'] Data directory to look in: /Users/ashish/Desktop/DS4W/sensorhub-analysis/data Sub directories for each Device ID found: ['f3eba7e5-dbda-4f4c-9fa8-8e8308b334f6', '5f680dfb-2510-4790-8f10-cb8724e7004c', '3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8'] Using data from /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_02_15Z-step_count/Internal Accelerometer_accelerometer.csv and /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_03_14Z-step_count_challenge/Internal Accelerometer_accelerometer.csv Using data from /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_02_15Z-step_count/Internal Accelerometer_accelerometer.csv and /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_03_14Z-step_count_challenge/Internal Accelerometer_accelerometer.csv
Experimental Design¶
Within-subject study: Each participant (N = 5) performs:
- Sit-to-stand under normal conditions
- Sit-to-stand while doing a cognitive task (serial subtraction)
Data collected:
- Timestamped acceleration on 3 axes (x, y, z) for ~30 seconds per trial
Step 1: Compute Acceleration Magnitude¶
We reduce the 3D accelerometer signal into a single scalar by computing the magnitude of free acceleration at each time point:
$$ \text{acc_mag}(t) = \sqrt{x_t^2 + y_t^2 + z_t^2} $$
This gives us a time-series that reflects total body movement intensity.
📉 Step 2: Feature Extraction — Mean Acceleration¶
We summarize the signal for each trial (one per participant per condition) by computing the mean acceleration magnitude:
$$ \bar{a} = \frac{1}{T} \sum_{t=1}^{T} \text{acc_mag}(t) $$
Where:
- T is the number of time points in the trial
- a' represents the average movement intensity
🔍 Step 3: Statistical Testing — Paired t-test¶
To assess whether the cognitive condition affects mean acceleration, we compare the values within participants using a paired t-test.
Let the difference for each participant be:
$$ D_i = a_{\text{normal},i} - a_{\text{cognitive},i} $$
We test the null hypothesis:
$$ H_0: \mu_D = 0 \quad \text{(no difference)} $$
With the t-statistic:
$$ t = \frac{\bar{D}}{s_D / \sqrt{n}} $$
Where:
- D' is the mean of the differences
- s_D is the standard deviation of the differences
- n is the number of participants
If the resulting p-value < 0.05, we reject ( H_0 ), concluding that cognitive load significantly alters movement.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
# Convert timestamps to datetime for better x-axis labels
# Create a relative time in seconds from the first timestamp
def visualize_data(df):
# Plot the acceleration data
plt.figure(figsize=(12, 8))
# Plot each axis
plt.subplot(3, 1, 1)
plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='X-axis')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration X-axis')
plt.grid(True)
plt.legend()
plt.subplot(3, 1, 2)
plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'g-', label='Y-axis')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration Y-axis')
plt.grid(True)
plt.legend()
plt.subplot(3, 1, 3)
plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'b-', label='Z-axis')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration Z-axis')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
# Combined view of all three axes
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='X-axis')
plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'g-', label='Y-axis')
plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'b-', label='Z-axis')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Free Acceleration - All Axes')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
# Plot the magnitude
plt.figure(figsize=(12, 5))
plt.plot(df['time_s'], df['acceleration_magnitude'], 'k-')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration Magnitude (m/s²)')
plt.title('Magnitude of Acceleration')
plt.grid(True)
plt.tight_layout()
plt.show()
# Visualize normal data
visualize_data(df_standard)
# Visualize challenge data
visualize_data(df_challenge)
# Compare both data x-axis acceleration
def compare_acceleration_x(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_x'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('X-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data x-axis acceleration
compare_acceleration_x(df_standard, df_challenge)
# Compare both data y-axis acceleration
def compare_acceleration_y(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_y'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Y-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data y-axis acceleration
compare_acceleration_y(df_standard, df_challenge)
# Compare both data z-axis acceleration
def compare_acceleration_z(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_z'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title('Y-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data z-axis acceleration
compare_acceleration_z(df_standard, df_challenge)
# Compare both data magnitude of acceleration
def compare_acceleration_magnitude(df, df_challenge):
plt.figure(figsize=(12, 6))
plt.plot(df['time_s'], df['acceleration_magnitude'], 'r-', label='Normal')
plt.plot(df_challenge['time_s'], df_challenge['acceleration_magnitude'], 'b-', label='Challenge')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration Magnitude (m/s²)')
plt.title('Magnitude of Acceleration Comparison')
plt.legend()
plt.show()
# Compare both data magnitude of acceleration
compare_acceleration_magnitude(df_standard, df_challenge)
# Compare x-acceleration across all participants
def compare_acceleration_x_all(dfs, axis='x'):
plt.figure(figsize=(20, 6))
for i, df in enumerate(dfs):
plt.plot(df['time_s'], df[f'freeAcceleration_m/s²_{axis}'], label=f'Participant {i+1}')
plt.xlabel('Time (seconds)')
plt.ylabel('Acceleration (m/s²)')
plt.title(f'{axis}-axis Acceleration Comparison')
plt.legend()
plt.show()
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand)
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand, 'y')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand, 'z')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'x')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'y')
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'z')
len(dfs_stand), dfs_stand
(5,
[ timestamp_ms freeAcceleration_m/s²_x freeAcceleration_m/s²_y \
0 1747033335167 -0.895215 2.819942
1 1747033335199 -0.580858 2.885744
2 1747033335215 -0.576072 2.963212
3 1747033335263 0.057129 3.147758
4 1747033335294 0.043071 3.035296
... ... ... ...
1093 1747033365375 -0.058325 0.618246
1094 1747033365407 -1.164407 0.292523
1095 1747033365423 -1.383351 0.353839
1096 1747033365471 -2.008774 0.601795
1097 1747033365503 -1.447957 1.105185
freeAcceleration_m/s²_z time_s acceleration_magnitude
0 8.994321 0.000 9.468437
1 8.695518 0.032 9.180248
2 8.683254 0.048 9.193007
3 9.101998 0.096 9.631096
4 9.285348 0.127 9.768959
... ... ... ...
1093 10.159028 30.208 10.177990
1094 10.748261 30.240 10.815106
1095 10.637293 30.256 10.732701
1096 9.495916 30.304 9.724698
1097 9.175877 30.336 9.354931
[1098 rows x 6 columns],
timestamp_ms freeAcceleration_m/s²_x freeAcceleration_m/s²_y \
0 1746707114626 -1.446162 2.251646
1 1746707114658 -1.409074 2.175973
2 1746707114707 -1.507179 2.025823
3 1746707114722 -1.503590 2.021038
4 1746707114754 -1.628914 2.047957
... ... ... ...
1178 1746707146530 -1.336391 0.938884
1179 1746707146562 -1.496411 1.640878
1180 1746707146578 -0.788435 1.118645
1181 1746707146610 -0.515653 1.587638
1182 1746707146642 0.235095 1.702493
freeAcceleration_m/s²_z time_s acceleration_magnitude
0 9.483952 0.000 9.854271
1 9.491131 0.032 9.838796
2 9.623633 0.081 9.949365
3 9.473783 0.096 9.802956
4 9.515657 0.128 9.868902
... ... ... ...
1178 9.347860 31.904 9.489464
1179 10.793724 31.936 11.019810
1180 9.958928 31.952 10.052524
1181 9.188140 31.984 9.338544
1182 8.387142 32.016 8.561420
[1183 rows x 6 columns],
timestamp_ms freeAcceleration_m/s²_x freeAcceleration_m/s²_y \
0 1746708696802 1.230210 3.256632
1 1746708696818 1.144068 3.308975
2 1746708696866 1.009472 3.437589
3 1746708696883 0.967299 3.452245
4 1746708696914 0.967897 3.504588
... ... ... ...
1146 1746708727458 -1.123729 1.488336
1147 1746708727490 -0.541077 1.222732
1148 1746708727506 -1.536192 2.203491
1149 1746708727539 -0.029910 2.172085
1150 1746708727555 0.255434 2.452643
freeAcceleration_m/s²_z time_s acceleration_magnitude
0 8.897113 0.000 9.553936
1 8.875278 0.016 9.540900
2 8.701201 0.064 9.409938
3 8.756235 0.081 9.461782
4 8.665906 0.112 9.397707
... ... ... ...
1146 6.812067 30.656 7.062731
1147 10.696217 30.688 10.779466
1148 10.473085 30.704 10.812066
1149 7.900801 30.737 8.193992
1150 6.884749 30.753 7.313035
[1151 rows x 6 columns],
timestamp_ms freeAcceleration_m/s²_x freeAcceleration_m/s²_y \
0 1746707353970 0.213859 3.412165
1 1746707353986 0.374477 3.434897
2 1746707354002 0.470190 3.475575
3 1746707354034 0.306580 3.707679
4 1746707354051 0.259920 3.750750
... ... ... ...
1100 1746707384371 -0.897608 1.856830
1101 1746707384402 -0.589233 1.917847
1102 1746707384434 -0.453739 2.145165
1103 1746707384450 -0.362513 2.029712
1104 1746707384483 -0.651147 2.011467
freeAcceleration_m/s²_z time_s acceleration_magnitude
0 9.294920 0.000 9.903744
1 9.021839 0.016 9.660866
2 8.756834 0.032 9.433072
3 8.500801 0.064 9.279251
4 8.576474 0.081 9.364379
... ... ... ...
1100 10.803893 30.401 10.998983
1101 8.788837 30.432 9.014931
1102 8.138288 30.464 8.428485
1103 8.234600 30.480 8.488803
1104 9.437891 30.513 9.671803
[1105 rows x 6 columns],
timestamp_ms freeAcceleration_m/s²_x freeAcceleration_m/s²_y \
0 1747033460847 -0.658026 1.848755
1 1747033460879 -0.723530 1.911865
2 1747033460927 -0.523729 2.000101
3 1747033460959 -0.455534 2.054537
4 1747033460975 -0.505185 2.107179
... ... ... ...
1083 1747033491055 -0.598804 2.568097
1084 1747033491135 -0.500100 2.051546
1085 1747033491167 -0.401097 2.318944
1086 1747033491183 -0.325125 2.359921
1087 1747033491215 0.594916 2.088037
freeAcceleration_m/s²_z time_s acceleration_magnitude
0 9.765707 0.000 9.960920
1 9.685548 0.032 9.898917
2 9.436396 0.080 9.660241
3 9.219545 0.112 9.456672
4 9.149555 0.128 9.402647
... ... ... ...
1083 9.646963 30.208 10.000879
1084 10.144073 30.288 10.361523
1085 9.937094 30.320 10.211964
1086 9.508180 30.336 9.802062
1087 10.854442 30.368 11.069450
[1088 rows x 6 columns]])
# Compare number of rows in each participant's data by plotting
import matplotlib.pyplot as plt
# Create a list to store the number of rows for each participant
num_rows_list_standard = [len(df) for df in dfs_stand]
num_rows_list_challenge = [len(df) for df in dfs_stand_challenge]
# PLot bar chart of number of rows for each participant with participant number on x-axis
plt.figure(figsize=(14, 6))
plt.bar(range(len(num_rows_list_standard)), num_rows_list_standard, label='Standard')
# Label each bar with the number of samples in the participant's data
for i, num_rows in enumerate(num_rows_list_standard):
plt.text(i, num_rows, str(num_rows), ha='center', va='bottom')
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Standard Task')
plt.legend()
<matplotlib.legend.Legend at 0x11403e650>
plt.figure(figsize=(12, 6))
plt.bar(range(len(num_rows_list_challenge)), num_rows_list_challenge, label='Challenge')
for i, num_rows in enumerate(num_rows_list_challenge):
plt.text(i, num_rows, str(num_rows), ha='center', va='bottom')
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Challenge Task')
plt.legend()
<matplotlib.legend.Legend at 0x133c46140>
# Plot a double, non overlapping bar chart of number of rows for standard and challenge tasks
count_df = pd.DataFrame({
'Standard': num_rows_list_standard,
'Challenge': num_rows_list_challenge
})
count_df.plot(kind='bar', figsize=(12, 6))
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Standard and Challenge Tasks')
plt.legend()
<matplotlib.legend.Legend at 0x11237b370>
# Calculate mean acceleration for each axis per participant
mean_acceleration_standard_x = [df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand]
mean_acceleration_challenge_x = [df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand_challenge]
mean_acceleration_standard_y = [df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand]
mean_acceleration_challenge_y = [df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand_challenge]
mean_acceleration_standard_z = [df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand]
mean_acceleration_challenge_z = [df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand_challenge]
# Plot and compare mean acceleration for each axis per participant
def plot_mean_acceleration(mean_acceleration_standard, mean_acceleration_challenge, axis='x'):
plt.figure(figsize=(12, 6))
plt.bar(range(len(mean_acceleration_standard)), mean_acceleration_standard, label='Standard')
plt.bar(range(len(mean_acceleration_challenge)), mean_acceleration_challenge, label='Challenge')
# Label each bar with the mean acceleration, rounded to 2 decimal places
for i, mean_acceleration in enumerate(mean_acceleration_standard):
# write text in blue color
plt.text(i, mean_acceleration, str(round(mean_acceleration, 4)), ha='center', va='bottom', color='blue')
for i, mean_acceleration in enumerate(mean_acceleration_challenge_x):
plt.text(i, mean_acceleration, str(round(mean_acceleration, 4)), ha='center', va='bottom', color='black')
plt.xlabel('Participant')
plt.ylabel(f"Mean Acceleration in {axis}-axis (m/s²)")
plt.title('Mean Acceleration in Standard and Challenge Tasks')
plt.legend()
# Mean acceleration for x axis
plot_mean_acceleration(mean_acceleration_standard_x, mean_acceleration_challenge_x, 'x')
# Mean acceleration for y axis
plot_mean_acceleration(mean_acceleration_standard_y, mean_acceleration_challenge_y, 'y')
# Mean acceleration for z axis
plot_mean_acceleration(mean_acceleration_standard_z, mean_acceleration_challenge_z, 'z')
# Plot sample means using qq plots
import statsmodels.api as sm
# Create a list to store the sample means for each participant
sample_means_standard_x = np.array([df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand])
sample_means_challenge_x = np.array([df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand_challenge])
sample_means_standard_y = np.array([df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand])
sample_means_challenge_y = np.array([df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand_challenge])
sample_means_standard_z = np.array([df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand])
sample_means_challenge_z = np.array([df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand_challenge])
fig, axs = plt.subplots(2, 3, figsize=(20, 12), sharex=True)
# Plot qq plot of sample means and add labels
sm.qqplot(sample_means_standard_x, line='45', fit=True, ax=axs[0, 0])
axs[0, 0].set_xlabel('Theoretical Quantiles')
axs[0, 0].set_ylabel('Sample Quantiles')
axs[0, 0].set_title('QQ Plot of Sample Means for Standard Task along x-axis')
axs[0, 0].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_x, line='45', fit=True, ax=axs[1, 0])
axs[1, 0].set_xlabel('Theoretical Quantiles')
axs[1, 0].set_ylabel('Sample Quantiles')
axs[1, 0].set_title('QQ Plot of Sample Means for Challenge Task along x-axis')
axs[1, 0].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_standard_y, line='45', fit=True, ax=axs[0, 1])
axs[0, 1].set_xlabel('Theoretical Quantiles')
axs[0, 1].set_ylabel('Sample Quantiles')
axs[0, 1].set_title('QQ Plot of Sample Means for Standard Task along y-axis')
axs[0, 1].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_y, line='45', fit=True, ax=axs[1, 1])
axs[1, 1].set_xlabel('Theoretical Quantiles')
axs[1, 1].set_ylabel('Sample Quantiles')
axs[1, 1].set_title('QQ Plot of Sample Means for Challenge Task along y-axis')
axs[1, 1].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_standard_z, line='45', fit=True, ax=axs[0, 2])
axs[0, 2].set_xlabel('Theoretical Quantiles')
axs[0, 2].set_ylabel('Sample Quantiles')
axs[0, 2].set_title('QQ Plot of Sample Means for Standard Task along z-axis')
axs[0, 2].legend()
# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_z, line='45', fit=True, ax=axs[1, 2])
axs[1, 2].set_xlabel('Theoretical Quantiles')
axs[1, 2].set_ylabel('Sample Quantiles')
axs[1, 2].set_title('QQ Plot of Sample Means for Challenge Task along z-axis')
axs[1, 2].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:20: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0, 0].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:27: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1, 0].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:34: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0, 1].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:41: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1, 1].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:48: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0, 2].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:55: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1, 2].legend()
<matplotlib.legend.Legend at 0x134fa2a70>
# Calculate magnitude of acceleration for each participant
mean_acceleration_standard_magnitude = np.array([df['acceleration_magnitude'].mean() for df in dfs_stand])
mean_acceleration_challenge_magnitude = np.array([df['acceleration_magnitude'].mean() for df in dfs_stand_challenge])
mean_acceleration_standard_magnitude, mean_acceleration_challenge_magnitude
(array([ 9.97595914, 9.93244123, 10.00495032, 9.93742912, 9.94257389]), array([9.9808255 , 9.96965113, 9.90034447, 9.96543908, 9.95135268]))
# Plot qq plot for mean acceleration of standard and challenge tasks
fig, axs = plt.subplots(1, 2, figsize=(20, 4), sharex=True)
# Plot qq plot for the mean magnitude of acceleration for standard and challenge tasks
sm.qqplot(mean_acceleration_standard_magnitude, line='45', fit=True, ax=axs[0])
axs[0].set_xlabel('Theoretical Quantiles')
axs[0].set_ylabel('Sample Quantiles')
axs[0].set_title('QQ Plot of Mean Magnitude of Acceleration for Standard Task')
axs[0].legend()
sm.qqplot(mean_acceleration_challenge_magnitude, line='45', fit=True, ax=axs[1])
axs[1].set_xlabel('Theoretical Quantiles')
axs[1].set_ylabel('Sample Quantiles')
axs[1].set_title('QQ Plot of Mean Magnitude of Acceleration for Challenge Task')
axs[1].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/205138737.py:8: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[0].legend() /var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/205138737.py:14: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. axs[1].legend()
<matplotlib.legend.Legend at 0x1368d4f40>
# Plot ecdf of sample means
import seaborn as sns
# Plot ecdf of sample means using subplots of grid 1,3 along x, y and z axis
fig, axs = plt.subplots(1, 3, figsize=(20, 6), sharex=True)
sns.ecdfplot(sample_means_standard_x, label='Standard', ax=axs[0])
sns.ecdfplot(sample_means_challenge_x, label='Challenge', ax=axs[0])
axs[0].set_xlabel('Mean Acceleration along x-axis (m/s²)')
axs[0].set_ylabel('ECDF')
axs[0].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[0].legend()
sns.ecdfplot(sample_means_standard_y, label='Standard', ax=axs[1])
sns.ecdfplot(sample_means_challenge_y, label='Challenge', ax=axs[1])
axs[1].set_xlabel('Mean Acceleration along y-axis (m/s²)')
axs[1].set_ylabel('ECDF')
axs[1].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[1].legend()
sns.ecdfplot(sample_means_standard_z, label='Standard', ax=axs[2])
sns.ecdfplot(sample_means_challenge_z, label='Challenge', ax=axs[2])
axs[2].set_xlabel('Mean Acceleration along z-axis (m/s²)')
axs[2].set_ylabel('ECDF')
axs[2].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[2].legend()
<matplotlib.legend.Legend at 0x136b0ed10>
fig, axs = plt.subplots(1, 2, figsize=(20, 4), sharex=True)
sns.ecdfplot(mean_acceleration_standard_magnitude, label='Standard', ax=axs[0])
sns.ecdfplot(mean_acceleration_challenge_magnitude, label='Challenge', ax=axs[1])
axs[0].set_xlabel('Mean Acceleration (m/s²)')
axs[0].set_ylabel('ECDF')
axs[0].set_title('ECDF of Mean Magnitude of Acceleration for Standard Task')
axs[0].legend()
axs[1].set_xlabel('Mean Acceleration (m/s²)')
axs[1].set_ylabel('ECDF')
axs[1].set_title('ECDF of Mean Magnitude of Acceleration for Challenge Task')
axs[1].legend()
<matplotlib.legend.Legend at 0x136b94370>
# Perform t-test for the magnitude of mean acceleration of standard and challenge tasks
mean_acc_standard = [df['acceleration_magnitude'].mean() for df in dfs_stand]
mean_acc_challenge = [df['acceleration_magnitude'].mean() for df in dfs_stand_challenge]
print(mean_acc_standard)
print(mean_acc_challenge)
[np.float64(9.97595913863206), np.float64(9.932441233984115), np.float64(10.0049503202501), np.float64(9.937429117145417), np.float64(9.942573890776329)] [np.float64(9.980825501450173), np.float64(9.969651130304943), np.float64(9.900344471083827), np.float64(9.965439082840906), np.float64(9.95135267805302)]
# Plot the magnitude of acceleration for each participant as a scatter plot
import matplotlib.pyplot as plt
participants = range(1, len(mean_acc_challenge) + 1)
plt.scatter(participants, mean_acc_standard, label='Standard')
plt.scatter(participants, mean_acc_challenge, label='Challenge')
<matplotlib.collections.PathCollection at 0x136c2ff70>
# Plot a bar chart of mean acceleration of standard and challenge tasks
participants = range(1, len(mean_acc_challenge) + 1)
plt.plot(participants, mean_acc_standard, marker='o', label='Standard')
plt.plot(participants, mean_acc_challenge, marker='o', label='Challenge')
plt.xlabel("Participant")
plt.ylabel("Mean Acceleration Magnitude")
plt.title("Sit-to-Stand: Standard vs Challenge")
plt.legend()
plt.grid(True)
plt.show()
# Paired t-test for the magnitude of mean acceleration of standard and challenge tasks
from scipy.stats import ttest_rel
t_stat, p_value = ttest_rel(mean_acc_standard, mean_acc_challenge)
print("Paired t-test result: \n")
print(f"t-statistic = {t_stat:.4f}")
print(f"p-value = {p_value:.4f}")
Paired t-test result: t-statistic = 0.2013 p-value = 0.8503
# Conclusion
print("Conclusion:")
print("*"*30)
if p_value < 0.05:
print("There is a significant difference in the mean acceleration magnitude between the standard and challenge tasks.")
else:
print("There is no significant difference in the mean acceleration magnitude between the standard and challenge tasks.")
Conclusion: ****************************** There is no significant difference in the mean acceleration magnitude between the standard and challenge tasks.